package com.project.bookstore.cart.service.impl;

import com.project.bookstore.book.mapper.BookMapper;
import com.project.bookstore.book.pojo.BookDetailVO;
import com.project.bookstore.cart.entity.Cart;
import com.project.bookstore.cart.mapper.CartMapper;
import com.project.bookstore.cart.pojo.CartClientLocalVO;
import com.project.bookstore.cart.pojo.CartVO;
import com.project.bookstore.cart.service.ICartService;
import com.project.bookstore.common.CommonResult;
import com.project.bookstore.exception.ServiceInternalException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private BookMapper bookMapper;

    @Override
    public int multiDeleteByIds(Long[] cartIds) {
        return cartMapper.multiDeleteByIds(cartIds);
    }

    @Override
    public CommonResult<Void> mergeLocalCart(Long userId, CartClientLocalVO[] clientLocalVOS) {
        log.debug("客户端提交本地购物车数据【{}】", Arrays.toString(clientLocalVOS));
        ArrayList<Long> bookIdsDB = cartMapper.selectBookIdsByUserId(userId);
        log.debug("用户【{}】数据库中购物车图书id数组：【{}】", userId, bookIdsDB);
        CartClientLocalVO[] cartsNew = Arrays.stream(clientLocalVOS).filter(e -> !bookIdsDB.contains(e.getBookId())).toArray(CartClientLocalVO[]::new);
        log.debug("去除数据库中原有数据，新增数据为：【{}】", Arrays.toString(cartsNew));
        if (cartsNew.length == 0) {
            log.debug("客户端本地购物车没有新数据");
            return CommonResult.ok();
        }
        ArrayList<Cart> carts = new ArrayList<>();
        for (CartClientLocalVO cartClientLocalVO : cartsNew) {
            Cart cart = new Cart();
            BeanUtils.copyProperties(cartClientLocalVO, cart);
            cart.setUserId(userId)
                    .setCreated(LocalDateTime.now())
                    .setCreated(LocalDateTime.now())
                    .setAmount(cart.getPrice().multiply(BigDecimal.valueOf(cart.getCount())));
            carts.add(cart);
        }
        if (cartsNew.length != cartMapper.multiAdd(carts.toArray(new Cart[0]))) {
            log.debug("未知原因合并客户端本地购物车数据时发生错误");
            throw new ServiceInternalException();
        }
        return CommonResult.ok();
    }

    /**
     * 转换客户端购物车数据为 map<bookId,num> 格式
     *
     * @param clientLocalVOS
     * @return
     */
    private Map<Long, Integer> cartClientVOToMap(CartClientLocalVO[] clientLocalVOS) {
        log.debug("客户端本地提交购物车数据：【{}】", Arrays.stream(clientLocalVOS).toArray());
        Map<Long, Integer> mapClientLocalVOS = Arrays.stream(clientLocalVOS).collect(Collectors.toMap(
                CartClientLocalVO::getBookId,
                CartClientLocalVO::getCount,
                (a, b) -> a
        ));
        log.debug("转为 map：【{}】", mapClientLocalVOS);
        return mapClientLocalVOS;
    }

    @Override
    public List<CartVO> getCartByBookIds(CartClientLocalVO[] clientLocalVOS) {
        Map<Long, Integer> mapClientLocalVOS = cartClientVOToMap(clientLocalVOS);
        Long[] bookIds = mapClientLocalVOS.keySet().toArray(new Long[0]);
        List<CartVO> cartVOS = bookMapper.listBookByIds(bookIds);
        cartVOS.forEach(e -> {
            int count = mapClientLocalVOS.get(e.getId());
            e.setCount(count);   //设置数量
            e.setAmount(BigDecimal.valueOf(count).multiply(e.getPrice()));  //总金额
        });
        log.debug("处理后的数据：【{}】", cartVOS);
        return cartVOS;
    }

    @Override
    public List<CartVO> getUserCartList(Long userId) {
        log.debug("根据用户ID【{}】获取购物车数据", userId);
        List<CartVO> cartVOS = cartMapper.listByUserId(userId);
        log.debug("购物车数据为【{}】", cartVOS);
        return cartVOS;
    }


    @Override
    public List<CartVO> getCartList() {
        return cartMapper.getCartList();
    }

    @Override
    public CommonResult<Void> add(Long bookId, Integer num, Long userId) {
    /*    UserDetailDO userDetailDO = new UserDetailDO();
        Long userId= userDetailDO.getId();*/

        //判断是否已经存在该图书ID的数据
        ArrayList<Long> bookIdsByUserId = cartMapper.selectBookIdsByUserId(userId);
        log.debug("用户【{}】原有购物车书籍ID列表为【{}】", userId, bookIdsByUserId);
        log.debug("bookId:{}", bookId);
        if (bookIdsByUserId.stream().anyMatch(e -> e.equals(bookId))) {
            Cart cartDB = cartMapper.selectByBookId(bookId);
            int count = cartDB.getCount() + num;
            log.debug("已有当前书籍【{}】，修改原数据的数量为【{}】", cartDB, count);
            if (cartMapper.updateCountById(cartDB.getId(), count) != 1) {
                log.warn("修改原购物车数据库数量时发生未知错误");
                throw new ServiceInternalException();
            }
            return CommonResult.ok();
        }
        BookDetailVO bookDetailById = bookMapper.getBookDetailById(bookId);
        if (bookDetailById == null) {
            log.warn("添加购物车时通过ID获取图书信息失败 bookId:【{}】", bookId);
            throw new ServiceInternalException();
        }
        log.debug("开始添加购物车，通过图书ID获取图书详情：【{}】", bookDetailById);
        Cart cart = new Cart();
        BeanUtils.copyProperties(bookDetailById, cart);
        cart.setUserId(userId).
                setBookId(bookId).
                setCount(num).
                setModified(LocalDateTime.now()).
                setCreated(LocalDateTime.now()).
                setAmount(cart.getPrice().multiply(BigDecimal.valueOf(cart.getCount())));
        log.debug("处理好的购物车数据为:【{}】", cart);
        if (cartMapper.insert(cart) != 1) {
            log.warn("往购物车中插入数据的时候发生未知错误");
            throw new ServiceInternalException();
        }
        return CommonResult.ok();
    }

    @Override
    public int deleteCartById(Integer id) {
        return cartMapper.deleteCartById(id);
    }
}
